 
module Schnell
  # this class is the super class for the iterator classes (buttons, links, spans etc
  # it would normally only be accessed by the iterator methods (spans, links etc) of browser
  
  class ElementCollections
    include Enumerable
    def initialize(page)
      @page = page
    end
    
    # returns the number of elements of the type in the page
    def length
      elements = @page.getByXPath(element_tag)
      if self.respond_to?(:element_types)
        selected_elements = elements.select{|element| (element_types).include?(element.getTypeAttribute)}
      else
        selected_elements = elements
      end
      selected_elements.length
    end
    
    # iterate through each of the elements in the collection in turn
    def each
      0.upto(self.length - 1) { |i| yield iterator_object(i) }
    end
    
    # allows access to a specific item in the collection
    def [](n)
      return iterator_object(n-1)
    end
    
    # this method creates an object of the correct type that the iterators use
    private
    def iterator_object(i)
      element_class.new(@page, :index, i + 1)
    end
  end
  
  # this class accesses the links in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#links method  
  class Links < ElementCollections
    def element_class; Link; end
    def element_tag; "//a"; end
  end
  
  # this class accesses the images in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#images method  
  class Images < ElementCollections
    def element_class; Image; end
    def element_tag; "//img"; end
  end

  # this class accesses the text fields in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#text_fields method    
  class TextFields < ElementCollections
    def element_class; TextField; end
    def element_tag; "//input"; end
    def element_types; ["text","password"]; end
  end
  
  # this class accesses the checkboxes in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#check_boxes method    
  class CheckBoxes < ElementCollections
    def element_class; CheckBox; end
    def element_tag; "//input"; end
    def element_types; ["checkbox"]; end    
  end
  
  # this class accesses the radio buttons in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#radios method    
  class Radios < ElementCollections
    def element_class; Radio; end
    def element_tag; "//input"; end
    def element_types; ["radio"]; end    
  end
  
  # this class accesses the select lists in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#select_lists method    
  class SelectLists < ElementCollections
    def element_class; SelectList; end
    def element_tag; "//select"; end
  end
  
  # this class accesses the buttons in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#buttons method    
  class Buttons < ElementCollections
    def element_class; Button; end
    def element_tag; "//input"; end
    def element_types; ["button","image","submit"]; end        
  end
  
  # this class accesses the list items in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#lis method    
  class Lis < ElementCollections
    def element_class; Li; end
    def element_tag; "//li"; end
  end
  
  # this class accesses the maps in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#maps method    
  class Maps < ElementCollections
    def element_class; Map; end
    def element_tag; "//map"; end
  end
  
  # this class accesses the pre formatted elements in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#pre method    
  class Pres < ElementCollections
    def element_class; Pre; end
    def element_tag; "//pre"; end
  end
  
  # this class accesses the areas in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#areas method    
  class Areas < ElementCollections
    def element_class; Area; end
    def element_tag; "//area"; end
  end
  
  # this class accesses the divs in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#divs method    
  class Divs < ElementCollections
    def element_class; Div; end
    def element_tag; "//div"; end
  end
  
  # this class accesses the spans in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#spans method    
  class Spans <  ElementCollections
    def element_class; Span; end
    def element_tag; "//span"; end
  end
  
  # this class accesses the ps in the document as a collection
  # Normally a user would not need to create this object as it is returned by the Schnell::Container#ps method    
  class Ps <  ElementCollections
    def element_class; P; end
    def element_tag; "//p"; end
  end  
end
